﻿using MathNet.Numerics;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NPOI.POIFS.Crypt;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using NPOI.XSSF.Streaming.Values;
using SixLabors.ImageSharp.Metadata.Profiles.Iptc;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace YB_Server_Windows
{
    public partial class YBListView : UserControl
    {
        private int NowWidth = 0;
        private Func<Dictionary<string, Object>, Color> _RowColor = null;
        public void SetDrawRow(Func<Dictionary<string, Object>, Color> drawRow)
        {
            _RowColor = drawRow;
        }
        private class DataMap
        {
            private int _maxRowCount = 0;
            public int MaxRowCount
            {
                get { return _maxRowCount; }
                set { _maxRowCount = value; }
            }
            private Dictionary<string, RowData> map = new Dictionary<string, RowData>();
            private List<RowData> list = new List<RowData>();
            public bool UseInsert = false;
            public int Count = 0;
            public void Add(RowData row)
            {
                if (!map.ContainsKey(row.Pkey))
                {
                    row.Index = list.Count - 1;
                    map.Add(row.Pkey, row);
                    if (UseInsert)
                    {
                        list.Insert(0, row);
                    }
                    else
                    {
                        list.Add(row);
                    }
                    Count++;
                    if (_maxRowCount > 0 && Count > _maxRowCount)
                    {
                        if (UseInsert)
                        {
                            // 移除最后一个元素
                            var oldestRow = list.Last();
                            map.Remove(oldestRow.Pkey);
                            list.RemoveAt(list.Count - 1);
                        }
                        // 选项2: 拒绝添加新元素（保持当前元素不变）
                        else
                        {
                            var oldestRow = list.First();
                            map.Remove(oldestRow.Pkey);
                            list.RemoveAt(0);
                        }
                    }
                }
            }
            public List<RowData> GetRange(int startindex, int endindex)
            {
                if (list.Count == 0)
                {
                    return null;
                }
                if (startindex < 0)
                {
                    startindex = 0;
                }
                if (endindex > list.Count - 1)
                {
                    endindex = list.Count - 1;
                }
                if (startindex >= 0 && startindex <= endindex)
                {
                    List<RowData> outData = new List<RowData>();
                    for (int i = startindex; i <= endindex; i++)
                    {
                        outData.Add(list[i]);
                    }
                    return outData;
                }
                return null;
            }
            public void Update(string pkey, RowData row, params string[] fields)
            {
                if (map.ContainsKey(pkey))
                {
                    int index = UseInsert ?
                        list.FindIndex(rd => rd.Pkey == pkey) :
                        list.FindLastIndex(rd => rd.Pkey == pkey);
                    if (index != -1)
                    {
                        // 更新指定字段
                        RowData existingRow = list[index];
                        foreach (var field in fields)
                        {
                            // 使用反射更新字段值
                            if (existingRow.Data.ContainsKey(field) && row.Data.ContainsKey(field))
                            {
                                existingRow.Data[field] = row.Data[field];
                            }
                        }

                        // 更新列表和映射
                        list[index] = existingRow;
                        map[row.Pkey] = existingRow;
                    }
                }
            }
            public void Update(RowData row, string[] fields)
            {
                if (map.ContainsKey(row.Pkey))
                {
                    // 找到要更新的行的索引
                    int index = UseInsert ?
                        list.FindIndex(rd => rd.Pkey == row.Pkey) :
                        list.FindLastIndex(rd => rd.Pkey == row.Pkey);

                    if (index != -1)
                    {
                        // 更新指定字段
                        RowData existingRow = list[index];
                        foreach (var field in fields)
                        {
                            // 使用反射更新字段值
                            if (existingRow.Data.ContainsKey(field) && row.Data.ContainsKey(field))
                            {
                                existingRow.Data[field] = row.Data[field];
                            }
                        }

                        // 更新列表和映射
                        list[index] = existingRow;
                        map[row.Pkey] = existingRow;
                    }
                }
            }
            public void Update(RowData row)
            {
                if (map.ContainsKey(row.Pkey))
                {
                    if (UseInsert)
                    {
                        //如果是从头开始添加的模式则从0开始查询,提高查询效率
                        int index = list.FindIndex(rd => rd.Pkey == row.Pkey);
                        if (index != -1)
                        {
                            list.RemoveAt(index);
                            list.Insert(index, row);
                            map[row.Pkey] = row;
                        }
                    }
                    else
                    {
                        //如果是从尾部追加的模式则从尾部开始查询，提高效率
                        int index = list.FindLastIndex(rd => rd.Pkey == row.Pkey);
                        if (index != -1)
                        {
                            list.RemoveAt(index);
                            list.Insert(index, row);
                            map[row.Pkey] = row;
                        }
                    }

                }
            }
            public void Delete(RowData row)
            {
                if (map.ContainsKey(row.Pkey))
                {
                    if (UseInsert)
                    {
                        //如果是从头开始添加的模式则从0开始查询,提高查询效率
                        int index = list.FindIndex(rd => rd.Pkey == row.Pkey);
                        if (index != -1)
                        {
                            list.RemoveAt(index);
                            map.Remove(row.Pkey);
                        }
                    }
                    else
                    {
                        //如果是从尾部追加的模式则从尾部开始查询，提高效率
                        int index = list.FindLastIndex(rd => rd.Pkey == row.Pkey);
                        if (index != -1)
                        {
                            list.RemoveAt(index);
                            map.Remove(row.Pkey);
                        }
                    }

                }
            }
            public void Clear()
            {
                map.Clear();
                list.Clear();
                Count = 0;
            }
            public void RemoveAt(int index)
            {
                if (index >= 0 && index < list.Count)
                {
                    // 获取要删除的行的主键
                    string pkeyToRemove = list[index].Pkey; // 假设 "id" 是主键
                    // 从 map 中删除对应的行
                    map.Remove(pkeyToRemove);

                    // 从 list 中删除对应的行
                    list.RemoveAt(index);
                    Count--;
                }
            }
            public bool ContainsKey(string key)
            {
                return map.ContainsKey(key);
            }

            public DataMap(bool useinstert)
            {
                this.UseInsert = useinstert;
            }
        }
        public class RowStyle
        {
            public Pen Pen { get; set; }
            public SolidBrush Brush { get; set; }
            public Font Font { get; set; }
            public int Height { get; set; }
        }
        public class RowData
        {
            public int Index { get; set; }
            public string Pkey { get; set; }
            public Dictionary<string, object> Data = new Dictionary<string, object>();
            public RowData(string pkey, Dictionary<string, object> data)
            {
                this.Pkey = pkey;
                this.Data = data;
            }
        }
        //列设置
        public class Columns
        {
            [DisplayName("标题")]
            public string Title { get; set; }
            [DisplayName("字段名")]
            public string Field { get; set; }
            [DisplayName("宽度")]
            public int Width { get; set; } = 80;
            public Columns(string title, string field, int width)
            {
                Title = title;
                Field = field;
                Width = width;
            }
        }
        //private Action<SolidBrush, Pen, Dictionary<string, string>> _formatter = null;
        private List<Columns> columns = new List<Columns>();
        private int _allHeight = 0;
        private int _allWidth = 0;
        private int _scollY = 0;
        private int _scollX = 0;
        //外框颜色
        private Pen _borderPen = new Pen(Color.Transparent);
        private SolidBrush _borderBrush = new SolidBrush(Color.Transparent);

        [Browsable(true)]
        [Category("1-外观")]
        [Description("表格边框颜色")]
        [DisplayName("表格边框颜色")]
        [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
        public Color BorderPen { get { return _borderPen.Color; } set { _borderPen = new Pen(value); Invalidate(); } }
        //字体参数
        private Font _columnsFont = new Font("Arial", 12, FontStyle.Regular);
        private SolidBrush _columnsColor = new SolidBrush(Color.Black);
        private Pen _columnsPen = new Pen(Color.Black);
        private StringFormat _columnsFormat = new StringFormat
        {
            // 设置文本对齐方式，例如左对齐
            Alignment = StringAlignment.Center,
            LineAlignment = StringAlignment.Center,
            // 设置文本截断为省略号
            Trimming = StringTrimming.EllipsisWord,
            // 设置格式化的宽度
            FormatFlags = StringFormatFlags.NoClip
        };
        private string _mainpkey = "";
        [Browsable(true)]
        [Category("2-表头")]
        [Description("表头字体")]
        [DisplayName("表头字体")]
        public Font ColummnsFont
        {
            get { return _columnsFont; }
            set { _columnsFont = value; Invalidate(); }
        }
        [Browsable(true)]
        [Category("2-表头")]
        [Description("表头字体颜色")]
        [DisplayName("表头字体颜色")]
        [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
        public Color ColummnsColor
        {
            get { return _columnsColor.Color; }
            set
            {
                _columnsColor = new SolidBrush(value);
                _columnsPen = new Pen(value); Invalidate();
            }
        }

        public int MaxRowCount
        {
            get { return Row.MaxRowCount; }
            set { Row.MaxRowCount = value; }
        }
        //控制参数[视觉参数]
        private int _columnsHeight = 30;
        [Browsable(true)]
        [Category("2-表头")]
        [DisplayName("表头高度")]
        public int ColumnsHeight
        {
            get { return _columnsHeight; }
            set { _columnsHeight = value; Invalidate(); }
        }
        [Browsable(true)]
        [Category("2-表头")]
        [DisplayName("表头边框颜色")]
        [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
        public Color ColumnsBorderColor
        {
            get { return _columnsPen.Color; }
            set { _columnsPen.Color = value; Invalidate(); }
        }
        [Browsable(true)]
        [Category("2-表头")]
        [DisplayName("表头背景颜色")]
        [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
        public Color ColumnsBrushColor
        {
            get { return _borderBrush.Color; }
            set { _borderBrush.Color = value; Invalidate(); }
        }
        private int _rowHeight = 25;
        [Browsable(true)]
        [Category("3-行属性")]
        [DisplayName("行高度")]
        public int RowHeight { get { return _rowHeight; } set { _rowHeight = value; Invalidate(); } }
        private SolidBrush _rowBackColor = new SolidBrush(Color.Transparent);
        [Browsable(true)]
        [Category("3-行属性")]
        [DisplayName("行背景色")]
        [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
        public Color RowBackColor
        {
            get { return _rowBackColor.Color; }
            set { _rowBackColor = new SolidBrush(value); Invalidate(); }
        }
        private Pen _rowborderPen = new Pen(Color.Black);
        [Browsable(true)]
        [Category("3-行属性")]
        [DisplayName("行边框颜色")]
        [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
        public Color RowBorderColor
        {
            get { return _rowborderPen.Color; }
            set { _rowborderPen = new Pen(value); Invalidate(); }
        }
        private Font _cellFont = new Font("Arial", 9, FontStyle.Regular);
        private SolidBrush _cellbackColor = new SolidBrush(Color.Transparent);
        private SolidBrush _cellColor = new SolidBrush(Color.Black);
        private StringFormat _cellFormat = new StringFormat
        {
            // 设置文本对齐方式，例如左对齐
            Alignment = StringAlignment.Center,
            LineAlignment = StringAlignment.Center,
            // 设置文本截断为省略号
            Trimming = StringTrimming.EllipsisWord,
            // 设置格式化的宽度
            FormatFlags = StringFormatFlags.NoWrap
        };
        [Browsable(true)]
        [Category("4-单元格属性")]
        [DisplayName("单元格字体")]
        public Font CellFont
        {
            get { return _cellFont; }
            set { _cellFont = value; Invalidate(); }
        }
        [Browsable(true)]
        [Category("4-单元格属性")]
        [DisplayName("单元格背景色")]
        [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
        public Color CellBackColor
        {
            get { return _cellbackColor.Color; }
            set { _cellbackColor = new SolidBrush(value); Invalidate(); }
        }
        [Browsable(true)]
        [Category("4-单元格属性")]
        [DisplayName("单元格字体色")]
        [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
        public Color CellPenColor
        {
            get { return _cellColor.Color; }
            set { _cellColor = new SolidBrush(value); Invalidate(); }
        }

        private DataMap Row = new DataMap(true);

        public void Delete(int index)
        {
            try
            {
                Row.RemoveAt(index);
                Invalidate();
            }
            catch (Exception ex)
            {

            }
        }
        public void ScrollTop()
        {
            _scollY = 0;
            vScrollBar1.Value = 0;
            Invalidate();
        }
        private List<RowData> _getRow<T>(T row)
        {
            List<RowData> outData = new List<RowData>();
            if (row is Array array)
            {
                //如果是数组
                foreach (T item in array)
                {
                    RowData data = _makeRow<T>(item);
                    if (data != null)
                    {
                        outData.Add(data);
                    }
                }
            }
            else if (row is List<T> list)
            {
                //如果是List
                foreach (T item in list)
                {
                    RowData data = _makeRow<T>(item);
                    if (data != null)
                    {
                        outData.Add(data);
                    }
                }
            }
            else if (typeof(T).IsValueType)
            {
                //如果是结构体
                RowData data = _makeRow<T>(row);
                if (data != null)
                {
                    outData.Add(data);
                }
            }

            return outData;
        }
        private RowData _makeRow<T>(T row)
        {
            try
            {
                string pkey = "";
                Dictionary<string, object> data = new Dictionary<string, object>();
                if (row is IDictionary)
                {
                    IDictionary dictionary = (IDictionary)row;
                    foreach (DictionaryEntry entry in dictionary)
                    {
                        string key = Convert.ToString(entry.Key);
                        object value = entry.Value;
                        if (key == _mainpkey)
                        {
                            pkey = Convert.ToString(value);
                        }
                        // 在这里处理键和值  
                        data[key] = value;
                    }
                    return new RowData(pkey, data);
                }
                else
                {
                    //是结构体
                    Type type = row.GetType();
                    FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    foreach (FieldInfo field in fields)
                    {
                        object value = field.GetValue(row);
                        data[field.Name] = value;
                        if (field.Name == _mainpkey)
                        {
                            pkey = Convert.ToString(value);
                        }
                    }
                    return new RowData(pkey, data);
                }

            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public void SetColumns(List<Columns> data)
        {
            columns = data;
            Invalidate();
        }
        public void SetData<T>(T row)
        {
            List<RowData> data = _getRow<T>(row);
            if (data.Count > 0)
            {
                Row.Clear();
                foreach (var item in data)
                {
                    Row.Add(item);
                }
                Invalidate();
            }
        }
        public void Update<T>(string pkey, T row, params string[] field)
        {
            RowData item = _makeRow<T>(row);
            if (Row.ContainsKey(pkey))
            {
                Row.Update(item, field);
                Invalidate();
            }
        }
        public void Update<T>(T row, params string[] field)
        {
            RowData item = _makeRow<T>(row);
            if (Row.ContainsKey(item.Pkey))
            {
                Row.Update(item, field);
                Invalidate();
            }
        }
        public void Update<T>(T row)
        {
            RowData item = _makeRow<T>(row);
            if (Row.ContainsKey(item.Pkey))
            {
                Row.Update(item);
                Invalidate();
            }
        }
        public void Delete<T>(T row)
        {
            RowData item = _makeRow<T>(row);
            if (Row.ContainsKey(item.Pkey))
            {
                Row.Delete(item);
                Invalidate();
            }
        }
        public void SetPkey(string pkey)
        {
            _mainpkey = pkey;
        }
        public void Add<T>(T row)
        {
            RowData item = _makeRow<T>(row);
            if (item != null)
            {
                Row.Add(item);
                Invalidate();
            }
        }
        public YBListView()
        {
            InitializeComponent();
            this.MouseWheel += new MouseEventHandler(This_MouseWheel);
            NowWidth = this.Width;
            //初始化默认值
            _columnsFont = this.Font;
        }
        private void This_MouseWheel(object sender, MouseEventArgs e)
        {
            // 在这里编写滚轮事件的响应代码
            int delta = e.Delta; // 获取滚轮的移动量，通常向前滚动是正值，向后滚动是负值
            _scollY -= delta;
            if (_scollY < 0)
            {
                _scollY = 0;
            }
            int max = Row.Count * _rowHeight - this.Height + _columnsHeight + 10;
            if (max < 0)
            {
                max = 0;
            }
            if (_scollY > max)
            {
                _scollY = max;
            }
            vScrollBar1.Minimum = 0;
            vScrollBar1.Maximum = max;
            vScrollBar1.Value = _scollY;
            Console.WriteLine(_scollY.ToString());
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (this.Height < (Row.Count * _rowHeight) + _columnsHeight + 10)
            {
                vScrollBar1.Visible = true;
                NowWidth = this.Width - vScrollBar1.Width;
            }
            else
            {
                vScrollBar1.Visible = false;
                NowWidth = this.Width;
            }
            //绘制内容
            Graphics g = e.Graphics;
            //绘制外框
            Rectangle borderRect = new Rectangle(0, 0, NowWidth - 1, this.Height - 1);
            g.DrawRectangle(_borderPen, borderRect);

            //先绘制表头
            int x = _scollX;
            if (vScrollBar1.Visible == false)
            {
                _scollY = 0;
            }
            int y = _scollY % _rowHeight;
            int firstVisibleIndex = (_scollY / _rowHeight);
            if (firstVisibleIndex * _rowHeight < _scollY)
            {
                y -= _rowHeight;
            }

            // 计算当前视图中可见的列表项数量
            int visibleCount = (int)Math.Ceiling((double)(Row.Count * _rowHeight - _columnsHeight) / _rowHeight);
            Console.WriteLine(_scollY.ToString() + "-" + firstVisibleIndex.ToString() + "-" + visibleCount.ToString());
            List<RowData> drawlist = Row.GetRange(firstVisibleIndex, visibleCount);
            if (drawlist != null)
            {
                foreach (RowData row in drawlist)
                {
                    //绘制行的内容
                    x = _scollX;
                    //绘制一条底边
                    Rectangle rowRect = new Rectangle(0, y + _columnsHeight, NowWidth - 1, _rowHeight);
                    if (_RowColor != null)
                    {
                        Color nowBakColor = _RowColor(row.Data);
                        SolidBrush nowbackColor = new SolidBrush(nowBakColor);
                        g.DrawRectangle(_columnsPen, rowRect);
                        g.FillRectangle(nowbackColor, rowRect);
                    }
                    else
                    {
                        g.DrawRectangle(_columnsPen, rowRect);
                        g.FillRectangle(_rowBackColor, rowRect);
                    }

                    for (int i = 0; i < columns.Count; i++)
                    {
                        try
                        {
                            Columns item = columns[i];
                            if (i == columns.Count - 1 && x < NowWidth)
                            {
                                item.Width = NowWidth - x;
                            }
                            if (x + item.Width > 0 && x < NowWidth)
                            {
                                Rectangle columnRect = new Rectangle(x, _columnsHeight + y, item.Width, _rowHeight);
                                g.FillRectangle(_cellbackColor, columnRect);
                                g.DrawRectangle(_columnsPen, columnRect);
                                if (row.Data.ContainsKey(item.Field))
                                {
                                    if (row.Data.TryGetValue(item.Field, out var value))
                                    {
                                        //Console.WriteLine("当前类型"+value.GetType().Name);
                                        if (value is string stringValue)
                                        {
                                            g.DrawString(stringValue, _cellFont, _cellColor, columnRect, _cellFormat);
                                        }
                                        else if (value is int intValue)
                                        {
                                            g.DrawString(intValue.ToString(), _cellFont, _cellColor, columnRect, _cellFormat);
                                        }
                                        else if (value is Image bitmapImage)
                                        {
                                            int sourceWidth = bitmapImage.Width;
                                            int sourceHeight = bitmapImage.Height;

                                            // 获取目标矩形的尺寸
                                            int destWidth = columnRect.Width;
                                            int destHeight = columnRect.Height;

                                            // 计算缩放比例，保持图像的宽高比
                                            float scaleX = (float)destWidth / sourceWidth;
                                            float scaleY = (float)destHeight / sourceHeight;
                                            float scale = Math.Min(scaleX, scaleY); // 选择较小的比例以保持图像不变形

                                            // 计算新的图像尺寸
                                            int newWidth = (int)(sourceWidth * scale);
                                            int newHeight = (int)(sourceHeight * scale);

                                            // 计算图像在目标矩形中的起始位置，使其居中
                                            int destX = columnRect.X + (destWidth - newWidth) / 2;
                                            int destY = columnRect.Y + (destHeight - newHeight) / 2;

                                            g.DrawImage(bitmapImage, destX, destY, newWidth, newHeight);
                                        }
                                    }
                                    //    object celldata = row.Data[item.Field];
                                    //switch 
                                    //g.DrawString(row.Data[item.Field], _cellFont, _cellColor, columnRect, _cellFormat);
                                }
                            }
                            x += item.Width;
                        }
                        catch (Exception ex)
                        {

                        }
                    }
                    y += _rowHeight;
                }
            }
            //绘制表头外框
            Rectangle columnsBorder = new Rectangle(0, 0, NowWidth - 1, _columnsHeight);
            g.FillRectangle(_borderBrush, columnsBorder);
            g.DrawRectangle(_columnsPen, columnsBorder);
            x = _scollX;
            for (int i = 0; i < columns.Count; i++)
            {
                Columns item = columns[i];
                if (i == columns.Count - 1 && x < NowWidth)
                {
                    item.Width = NowWidth - x;
                }
                if (x + item.Width > 0 && x < NowWidth)
                {
                    //只有X坐标达到了屏幕内才绘制
                    Rectangle columnRect = new Rectangle(x, 0, item.Width, _columnsHeight);
                    //绘制边框及颜色
                    g.DrawRectangle(_columnsPen, columnRect);
                    //绘制表头文字
                    g.DrawString(item.Title, _columnsFont, _columnsColor, columnRect, _columnsFormat);
                }
                x += item.Width;
            }
        }

        private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            _scollY = vScrollBar1.Value;
            Invalidate();
        }
    }
}
